package com.hp.attendance.util;


import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class BaseDAO {
    /**
     * 增删改方法
     * @param sql sql语句
     * @param obj 参数数组
     */
    public void addOrUpdOrDel(String sql,Object[] obj) throws SQLException, IOException, ClassNotFoundException {
        Connection conn = DBUtil.getConn();
        PreparedStatement ps = conn.prepareStatement(sql);
        //设置参数
        for (int i = 0; i < obj.length; i++) {
            ps.setObject(i+1,obj[i]);
        }
        ps.executeUpdate();
        DBUtil.close(null,ps,conn);
    }

    /**
     * 查询多条记录的方法
     * @param sql sql语句
     * @param obj 参数数组
     * @param o   返回的数据对象
     * @param <T>  泛型方法
     * @return   List集合数据
     */
    public <T> List<T> queryList(String sql,Object[] obj,T o) throws SQLException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        List<T> list = new ArrayList<T>();
        // 获取数据库连接
        Connection conn = DBUtil.getConn();
        // 获取ps对象 用来执行sql语句  获取对象的时候就已经预编译了
        PreparedStatement ps = conn.prepareStatement(sql);
        //设置参数
        for (int i = 0; i <obj.length ; i++) {
            ps.setObject(i+1,obj[i]);
        }
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            // 通过反射的方式来获取字段名
            // 通过字节码对象 获取 当前对象的所有属性的对象
            Field[] fields = o.getClass().getDeclaredFields();
            // 创建新的实例化对象
            Object u = o.getClass().newInstance(); // new Object();  new User();  new Student();
            // 取出每一个属性的对象，用来获取数据库字段对应的值  并把这个值在设置到u的对象中
            // String username=ps.getString("username");  u.setUsername(username);
            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();
                Object columnValue = rs.getObject(name);
                field.set(u,columnValue);
            }
            //把Object对象强转为泛型
            T tt =(T)u;
            list.add(tt);
        }
        DBUtil.close(rs,ps,conn);
        return list;
    }

    /**
     * 查询单挑记录
     * @param sql sql语句
     * @param obj 参数数组
     * @param o   返回对象
     * @param <T>  泛型
     * @return  返回单个对象
     */
    public <T> T queryOne(String sql,Object[] obj,T o) throws SQLException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 获取数据库连接
        Connection conn = DBUtil.getConn();
        // 获取ps对象 用来执行sql语句  获取对象的时候就已经预编译了
        PreparedStatement ps = conn.prepareStatement(sql);
        //设置参数
        for (int i = 0; i <obj.length ; i++) {
            ps.setObject(i+1,obj[i]);
        }
        ResultSet rs = ps.executeQuery();
        Object u = o.getClass().newInstance(); // new Object();  new User();  new Student();
        if (rs.next()){
            // 通过反射的方式来获取字段名
            // 通过字节码对象 获取 当前对象的所有属性的对象
            Field[] fields = o.getClass().getDeclaredFields();
            // 创建新的实例化对象
            // 取出每一个属性的对象，用来获取数据库字段对应的值  并把这个值在设置到u的对象中
            // String username=ps.getString("username");  u.setUsername(username);
            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();
                Object columnValue = rs.getObject(name);
                field.set(u,columnValue);
            }
            //把Object对象强转为泛型
        }
        T tt =(T)u;
        DBUtil.close(rs,ps,conn);
        return tt;
    }

    //查询记录条数
    public int queryCount(String sql,Object[] obj) throws SQLException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 获取数据库连接
        Connection conn = DBUtil.getConn();
        // 获取ps对象 用来执行sql语句  获取对象的时候就已经预编译了
        PreparedStatement ps = conn.prepareStatement(sql);
        //设置参数
        for (int i = 0; i <obj.length ; i++) {
            ps.setObject(i+1,obj[i]);
        }
        ResultSet rs = ps.executeQuery();
        int count=0;
        if (rs.next()){
             count = rs.getInt(1);
        }
        DBUtil.close(rs,ps,conn);
        return count;
    }


}
